net: can: fix memory leak in mcba_urb_unlink
syzbot reported memory leak in mcb_usb driver.
The problem was in not freed usb coherents.
usb_kill_anchored_urbs() won't free them, so adding
explicit usb_free_coherent for all alocated urbs will
solve this problem
Reported-by: syzbot+57281c762a3922e14dfe@syzkaller.appspotmail.com
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
Change-Id: Id6e1db7f215ff971e0282ccdda2b06c16784dee7
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index 1f649d1..b8fac53 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -78,6 +78,7 @@ struct mcba_priv {
struct usb_anchor tx_submitted;
struct usb_anchor rx_submitted;
struct can_berr_counter bec;
+ void *rxbuf[MCBA_MAX_RX_URBS];
bool usb_ka_first_pass;
bool can_ka_first_pass;
bool can_speed_check;
@@ -666,6 +667,8 @@ static int mcba_usb_start(struct mcba_priv *priv)
break;
}
+ priv->rxbuf[i] = buf;
+
/* Drop reference, USB core will take care of freeing it */
usb_free_urb(urb);
}
@@ -708,7 +711,14 @@ static int mcba_usb_open(struct net_device *netdev)
static void mcba_urb_unlink(struct mcba_priv *priv)
{
+ int i;
+
usb_kill_anchored_urbs(&priv->rx_submitted);
+
+ for (i = 0; i < MCBA_MAX_RX_URBS; ++i)
+ usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
+ priv->rxbuf[i], 0);
+
usb_kill_anchored_urbs(&priv->tx_submitted);
}